import 'dart:async';
import 'dart:ui' as ui;
import 'dart:typed_data';
import 'dart:io';

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
import 'package:google_mlkit_commons/google_mlkit_commons.dart';
import 'package:image_gallery_saver_plus/image_gallery_saver_plus.dart';
import 'package:image_picker/image_picker.dart';
import 'painters/face_detector_painter.dart';

class FaceDetectorPage extends StatefulWidget {
  @override
  _FaceDetectorPageState createState() => _FaceDetectorPageState();
}

class _FaceDetectorPageState extends State<FaceDetectorPage> {
  final FaceDetector _faceDetector = FaceDetector(
    options: FaceDetectorOptions(
      enableContours: true,
      enableLandmarks: true,
    ),
  );
  final ImagePicker _picker = ImagePicker();
  CustomPaint? _customPaint;
  double aspectRatio = 1;

  Uint8List? _croppedImageBytes;
  Uint8List? _selectedImageBytes;
  String? _selectedImagePath;
  bool _useSelectedImage = false;

  Future<void> _processImage() async {
    // 检查是否使用选择的图片
    if ( _selectedImageBytes == null) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('还没选择图片呢～')),
      );
      return;
    }
    // 获取图片尺寸
    ui.Codec codec = await ui.instantiateImageCodec(_selectedImageBytes!);
    ui.FrameInfo frame = await codec.getNextFrame();
    ui.Image img = frame.image;
    aspectRatio = img.width / img.height;

    // 创建InputImage
    final inputImage = InputImage.fromFilePath(_selectedImagePath!);
    final faces = await _faceDetector.processImage(inputImage);
    debugPrint(faces.length.toString());

    // 如果检测到人脸，获取第一个face的boundingBox并进行抠图
    if (faces.isNotEmpty) {
      final firstFace = faces.first;
      final boundingBox = firstFace.boundingBox;
      // 抠图
      _croppedImageBytes =
          await _cropImage(_selectedImageBytes!, img, boundingBox);
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('没有识别到人脸')),
      );
    }

    final painter = FaceDetectorPainter(
      faces,
      Size(img.width.toDouble(), img.height.toDouble()),
      InputImageRotation.rotation0deg
    );
    setState(() {
      _customPaint = CustomPaint(painter: painter);
    });
  }

  Future<Uint8List> _cropImage(
      Uint8List originalBytes, ui.Image image, Rect boundingBox) async {
    // 创建一个新的画布来绘制抠图
    final pictureRecorder = ui.PictureRecorder();
    final canvas = Canvas(pictureRecorder);

    // 只绘制boundingBox区域内的图片
    canvas.drawImageRect(
      image,
      boundingBox,
      Rect.fromLTWH(0, 0, boundingBox.width, boundingBox.height),
      Paint(),
    );

    // 结束绘制并获取图片
    final picture = pictureRecorder.endRecording();
    final croppedImage = await picture.toImage(
        boundingBox.width.toInt(), boundingBox.height.toInt());

    // 将图片转换为字节数据
    final byteData =
        await croppedImage.toByteData(format: ui.ImageByteFormat.png);
    return byteData!.buffer.asUint8List();
  }

  @override
  void dispose() {
    _faceDetector.close();
    super.dispose();
  }

  Future<void> _saveImageToGallery() async {
    if (_croppedImageBytes == null) {
      return;
    }
    try {
      // 保存抠图后的图片到相册
      final result = await ImageGallerySaverPlus.saveImage(_croppedImageBytes!);
      if (result['isSuccess']) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('抠图后的图片已保存到相册')),
        );
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('保存抠图图片失败')),
        );
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('保存图片时出错: $e')),
      );
    }
  }

  Future<void> _pickImageFromGallery() async {
    _croppedImageBytes = null;
    _customPaint = null;
    final XFile? pickedFile =
        await _picker.pickImage(source: ImageSource.gallery);

    if (pickedFile != null) {
      // 读取选择的图片
      final bytes = await File(pickedFile.path).readAsBytes();

      setState(() {
        _selectedImageBytes = bytes;
        _selectedImagePath = pickedFile.path;
        _useSelectedImage = true;
      });

      // 显示提示
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('图片选择成功')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Face Detector'),
        leading: IconButton(
          icon: const Icon(Icons.photo_library),
          onPressed: _pickImageFromGallery,
        ),
        actions: [
          IconButton(
            icon: const Icon(Icons.save),
            onPressed: _saveImageToGallery,
          ),
        ],
      ),
      body: _selectedImagePath != null
          ?
          // 显示带有人脸框的图片
          AspectRatio(
              aspectRatio: aspectRatio,
              child: Stack(
                fit: StackFit.expand,
                children: [
                  // 根据是否使用选择的图片来显示不同的图片
                  if (_useSelectedImage && _selectedImagePath != null)
                    Image.file(File(_selectedImagePath!))
                  else
                    Image.asset(_selectedImagePath!),
                  if (_customPaint != null) _customPaint!,
                ],
              ))
          : Container(
              alignment: Alignment.center,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [Text("1.左上角选择图片\n 2.右下角人脸识别 \n 3.右上角导出图片")],
              ),
            ),
      floatingActionButton: FloatingActionButton(
        onPressed: _processImage,
        child: const Icon(Icons.visibility),
      ),
    );
  }
}
